package cz.zcu.fav.rat.managed.bean.calendar;

import java.util.Date;

import org.joda.time.LocalDateTime;
import org.primefaces.model.DefaultScheduleEvent;

import cz.zcu.fav.rat.beans.Period;
import cz.zcu.fav.rat.beans.PickAction;
import cz.zcu.fav.rat.beans.Reservation;
import cz.zcu.fav.rat.beans.Object;
import cz.zcu.fav.rat.beans.ReturnAction;
import cz.zcu.fav.rat.beans.User;
import cz.zcu.fav.rat.dataaccess.service.SettingsFactory;
import cz.zcu.fav.rat.managed.bean.SpringBeanFactory;
import cz.zcu.fav.rat.managed.locale.LocaleMessageFactory;

public class ReservationEvent extends DefaultScheduleEvent
{
	private static final long serialVersionUID = 2848928962653729719L;

	private boolean periodical;
	private int numberOfWeeks = 1;
	private Reservation reservation;
	private Period period;
	private Object object;
	private User user;
	private boolean enabled;
	private StyleClass styleClass = StyleClass.DEFAULT;
	private SettingsFactory settingsFactory;

	public SettingsFactory getSettingsFactory()
	{
		if (settingsFactory == null)
		{
			settingsFactory = SpringBeanFactory.getInstance().getBean(
					SettingsFactory.class);
		}

		return settingsFactory;
	}

	public boolean isPickable()
	{
		if (period.getPickAction() == PickAction.NOT_PICKED)
		{
			LocalDateTime range = LocalDateTime.now().plus(
					getSettingsFactory().getMinimumReservationDuration());
			return period.getFromDate().isBefore(range) && !period.getToDate().isBefore(LocalDateTime.now());
		}
		return false;
	}

	public String getPickStatus()
	{
		switch (period.getPickAction())
		{
		case NOT_PICKABLE:
			return LocaleMessageFactory
					.getLocale("properties.period.state.pickup.notpickable");
		case PICKED:
			return LocaleMessageFactory
					.getLocale("properties.period.state.pickup.picked");
		case NOT_PICKED:
			return LocaleMessageFactory
					.getLocale("properties.period.state.pickup.notpicked");
		default:
			return null;
		}
	}

	public String getReturnStatus()
	{
		switch (period.getReturnAction())
		{
		case NOT_RETURNABLE:
			return LocaleMessageFactory
					.getLocale("properties.period.state.returnitback.notreturnable");
		case NOT_RETURNED:
			return LocaleMessageFactory
					.getLocale("properties.period.state.returnitback.notreturned");
		case RETURNED:
			return LocaleMessageFactory
					.getLocale("properties.period.state.returnitback.returned");
		default:
			return null;
		}
	}

	public boolean isDeletable()
	{
		LocalDateTime now = LocalDateTime.now();
		return period.getFromDate().isAfter(now);
	}

	public boolean isReturnable()
	{
		return (period.getReturnAction() == ReturnAction.NOT_RETURNED && (period
				.getPickAction() == PickAction.PICKED || period.getPickAction() == PickAction.NOT_PICKABLE));
	}

	public Object getObject()
	{
		return object;
	}

	public void setObject(Object object)
	{
		this.object = object;
	}

	public ReservationEvent(String title, Date start, Date end, User user,
			Object object, Reservation reservation, Period period)
	{
		super(title, start, end);
		this.user = user;
		this.object = object;
		this.reservation = reservation;
		this.period = period;
		init();
	}

	private void init()
	{
		if (reservation == null || period == null)
		{
			// We are newly created
			return;
		}

		if (!period.isValid())
		{
			styleClass = StyleClass.GREY;
			return;
		}

		numberOfWeeks = reservation.getPeriods().size();
		if (period.getFromDate().isBefore(LocalDateTime.now()))
		{
			setEditable(false);
			if (period.getToDate().isBefore(LocalDateTime.now()))
			{
				// past
				if (period.getReturnAction() == ReturnAction.NOT_RETURNED)
				{
					styleClass = StyleClass.RED;
				} else
				{
					styleClass = StyleClass.GREY;
				}
			} else
			{
				// now
				if (period.getPickAction() == PickAction.NOT_PICKED)
				{
					styleClass = StyleClass.RED;
				} else
				{
					if (period.getReturnAction() == ReturnAction.RETURNED)
					{
						styleClass = StyleClass.GREY;
					} else if (period.getReturnAction() == ReturnAction.NOT_RETURNABLE)
					{
						styleClass = StyleClass.YELLOW;
					} else
					{
						styleClass = StyleClass.GREEN;
					}

				}
			}

		} else
		{
			// future
			if (period.getPickAction() == PickAction.NOT_PICKED)
			{
				styleClass = StyleClass.BLUE;
			} else
			{
				styleClass = StyleClass.YELLOW;
			}
		}
	}
	
	public Period getPeriod()
	{
		return period;
	}

	public void setPeriod(Period period)
	{
		this.period = period;
	}

	public boolean isPeriodical()
	{
		return periodical;
	}

	public void setPeriodical(boolean periodical)
	{
		this.periodical = periodical;
	}

	public int getNumberOfWeeks()
	{
		return numberOfWeeks;
	}

	public void setNumberOfWeeks(int numberOfWeeks)
	{
		this.numberOfWeeks = numberOfWeeks;
	}

	public User getUser()
	{
		return user;
	}

	public void setUser(User user)
	{
		this.user = user;
	}

	public LocalDateTime since()
	{
		return new LocalDateTime(getStartDate());
	}

	public LocalDateTime to()
	{
		return new LocalDateTime(getEndDate());
	}

	public boolean isEnabled()
	{
		return enabled;
	}

	public void setEnabled(boolean enabled)
	{
		this.enabled = enabled;
	}

	@Override
	public String getStyleClass()
	{
		return styleClass.toString();
	}

	protected enum StyleClass
	{
		DEFAULT(""), GREY("public-grey"), BLUE("public-blue"), RED("public-red"), YELLOW(
				"public-yellow"), GREEN("public-green");

		private String styleClass;

		private StyleClass(String styleClass)
		{
			this.styleClass = styleClass;

		}

		@Override
		public String toString()
		{
			return styleClass;
		}
	}

}
